package com.warrior.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Shawn on 2017/3/24.
 */
public class ServerResponse<T> {

    public static final String YYYY_MM_DD = "yyyy/MM/dd";
    public static final String YYYY_MM_DD_HH_MM = "yyyy/MM/dd HH:mm";
    /**
     * 响应状态
     */
    private int status;
    /**
     * 错误信息
     */
    private List<String> errorMsg;
    /**
     * 提示信息
     */
    private Map<String, String> noteMsg;
    /**
     * 响应数据
     */
    private T data;

    /**
     * mapper : 转换器
     */
    private ObjectMapper objectMapper;
    /**
     * 用于设置日期格式，默认yyyy/MM/dd hh:mm
     */
    private String pattern = "yyyy/MM/dd HH:mm";
    /**
     * 日期格式,缺省是 yyyy/MM/dd hh:mm
     */
    private DateFormat dateFormat = new SimpleDateFormat(pattern);
    /**
     * 创建一个新的实例 ServerResponse.
     */
    public ServerResponse() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.setDateFormat(dateFormat);
    }
    /**
     *
     * <p>Title: setPattern</p>
     * <p>Description: 修改日期格式 </p>
     * @param pattern 日期格式
     */
    public void setPattern(String pattern) {
        if(pattern!=null&&pattern.length()>0){
            this.dateFormat = new SimpleDateFormat(pattern);
            this.objectMapper.setDateFormat(this.dateFormat);
        }
    }


    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public List<String> getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(List<String> errorMsg) {
        this.errorMsg = errorMsg;
    }

    public Map<String, String> getNoteMsg() {
        return noteMsg;
    }

    public void setNoteMsg(Map<String, String> noteMsg) {
        this.noteMsg = noteMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    /**
     *
     * <p>
     * Title: setData
     * </p>
     * <p>
     * Description: 将字符串data转成指定对象data
     * </p>
     * @param dataStr
     *            字符串
     * @param type 需要转换的类型
     * @throws IOException
     */
    public void setData(String dataStr, Class<T> type) throws IOException {
        this.data = this.objectMapper.readValue(dataStr, type);
    }

    /**
     *
     * <p>
     * Title: hasErrorMsg
     * </p>
     * <p>
     * Description: 是否存在错误信息
     * </p>
     * @return boolean
     */
    public boolean hasErrorMsg() {
        return this.errorMsg != null && !this.errorMsg.isEmpty();
    }

    /**
     *
     * <p>
     * Title: numOfErrorMsg
     * </p>
     * <p>
     * Description: 错误信息的数量
     * </p>
     *
     * @return int
     */
    public int numOfErrorMsg() {
        if (this.errorMsg == null) {
            return 0;
        }
        return this.errorMsg.size();
    }

    /**
     *
     * <p>
     * Title: addErrorMsg
     * </p>
     * <p>
     * Description: 添加错误信息
     * </p>
     *
     * @param errorMsg
     *            错误信息内容
     */
    public void addErrorMsg(String errorMsg) {
        if (this.errorMsg == null) {
            this.errorMsg = new ArrayList<>();
        }
        this.errorMsg.add(errorMsg);
    }
    /**
     *
     * <p>Title: addErrorMsg</p>
     * <p>Description: 添加错误信息 </p>
     * @param errorMsg 错误信息
     */
    public void addErrorMsg(List<String> errorMsg) {
        if (this.errorMsg == null) {
            this.errorMsg = new ArrayList<>();
        }
        this.errorMsg.addAll(errorMsg);
    }
    /**
     *
     * <p>
     * Title: hasNoteMsg
     * </p>
     * <p>
     * Description: 是否存在提示信息
     * </p>
     *
     * @return boolean
     */
    public boolean hasNoteMsg() {
        return this.noteMsg != null && !this.noteMsg.isEmpty();
    }
    /**
     *
     * numOfNoteMsg
     *
     * @Title: numOfNoteMsg
     * @Description: 提醒消息的数量
     * @return
     */
    public int numOfNoteMsg() {
        if (this.noteMsg == null || this.noteMsg.isEmpty()) {
            return 0;
        }
        return this.noteMsg.size();
    }

    /**
     *
     * <p>
     * Title: putNoteMsg
     * </p>
     * <p>
     * Description: 添加提示信息
     * </p>
     *
     * @param name
     *            提示信息的名字
     * @param noteMsg
     *            提示信息内容
     */
    public void putNoteMsg(String name, String noteMsg) {
        if (this.noteMsg == null) {
            this.noteMsg = new HashMap<>();
        }
        this.noteMsg.put(name, noteMsg);
    }
    /**
     *
     * <p>Title: putNoteMsg</p>
     * <p>Description: 添加提示信息 </p>
     *
     * @param noteMsg 提示信息
     */
    public void putNoteMsg(Map<String,String> noteMsg) {
        if (this.noteMsg == null) {
            this.noteMsg = new HashMap<>();
        }
        this.noteMsg.putAll(noteMsg);
    }

    /**
     *
     * <p>
     * Title: getNoteMsgByName
     * </p>
     * <p>
     * Description: 根据name获取对应的提示信息
     * </p>
     *
     * @param name
     * @return
     */
    public String getNoteMsgByName(String name) {
        if (this.noteMsg == null) {
            return null;
        }
        return this.noteMsg.get(name);
    }

    /**
     *
     * <p>
     * Title: toJsonString
     * </p>
     * <p>
     * Description: 将响应数据结构转换成json字符串
     * </p>
     * @return String
     * @throws JsonProcessingException
     */
    public String toJsonString() throws JsonProcessingException {
        return this.objectMapper.writeValueAsString(this);
    }

    /**
     *
     * <p>
     * Title: toJsonString
     * </p>
     * <p>
     * Description: 将响应数据结构转换成json字符串(根据给定的日期格式)
     * </p>
     * @param pattern
     *            日期格式(默认 yyyy-MM-dd HH:mm:ss)
     * @return
     * @throws JsonProcessingException
     */
    public String toJsonString(String pattern) throws JsonProcessingException {
        if (pattern != null && pattern.length() > 0) {
            this.dateFormat = new SimpleDateFormat(pattern);
            this.objectMapper.setDateFormat(this.dateFormat);
        }
        return this.objectMapper.writeValueAsString(this);
    }

    /**
     *
     * <p>
     * Title: build
     * </p>
     * <p>
     * Description: 创建一个响应数据
     * </p>
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息（默认key为msg）
     * @param data
     *            响应数据
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> build(String code, String errorMsg, String noteMsg, T data) {
        ServerResponse<T> res = new ServerResponse<>();
        if (errorMsg != null && errorMsg.length() > 0) {
            res.addErrorMsg(errorMsg);
        }
        if (noteMsg != null && noteMsg.length() > 0) {
            res.putNoteMsg("msg", noteMsg);
        }
        if(data!=null){
            res.setData(data);
        }
        return res;
    }
    /**
     *
     * <p>Title: buildToJsonString</p>
     * <p>Description: 创建一个响应数据，并转换成json字符串 </p>
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息（默认key为msg）
     * @param data
     *            响应数据
     * @return String
     * @throws JsonProcessingException
     */
    public static <T> String buildToJsonString(String code, String errorMsg, String noteMsg, T data) throws JsonProcessingException {
        return ServerResponse.build(code, errorMsg, noteMsg, data).toJsonString();
    }
    /**
     *
     * <p>Title: build</p>
     * <p>Description:  </p>
     *
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息（默认key为msg）
     * @param data
     *            响应数据
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> build(String code, List<String> errorMsg, String noteMsg, T data) {
        ServerResponse<T> res = new ServerResponse<>();
        if (errorMsg != null && !errorMsg.isEmpty()) {
            res.addErrorMsg(errorMsg);
        }
        if (noteMsg != null && noteMsg.length() > 0) {
            res.putNoteMsg("msg", noteMsg);
        }
        if(data!=null){
            res.setData(data);
        }
        return res;
    }
    /**
     *
     * <p>Title: buildToJsonString</p>
     * <p>Description: 创建一个响应数据，并转换成json字符串 </p>
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息（默认key为msg）
     * @param data
     *            响应数据
     * @return String
     * @throws JsonProcessingException
     */
    public static <T> String buildToJsonString(String code, List<String> errorMsg, String noteMsg, T data) throws JsonProcessingException {
        return ServerResponse.build(code, errorMsg, noteMsg, data).toJsonString();
    }
    /**
     *    * @param code
     *            响应状态码
     * <p>Title: build</p>
     * <p>Description: 创建一个响应数据 </p>

     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息
     * @param data
     *            响应数据
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> build(String code, String errorMsg, Map<String,String> noteMsg, T data) {
        ServerResponse<T> res = new ServerResponse<>();
        if (errorMsg != null && errorMsg.length() > 0) {
            res.addErrorMsg(errorMsg);
        }
        if (noteMsg != null && !noteMsg.isEmpty()) {
            res.setNoteMsg(noteMsg);
        }
        if(data!=null){
            res.setData(data);
        }
        return res;
    }
    /**
     *
     * <p>Title: buildToJsonString</p>
     * <p>Description: 创建一个响应数据，并转换成json字符串 </p>
     *
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息
     * @param data
     *            响应数据
     * @return String
     * @throws JsonProcessingException
     */
    public static <T> String buildToJsonString(String code, String errorMsg, Map<String,String> noteMsg, T data) throws JsonProcessingException {
        return ServerResponse.build(code, errorMsg, noteMsg, data).toJsonString();
    }
    /**
     *
     * <p>Title: build</p>
     * <p>Description: 创建一个响应数据 </p>
     *
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息
     * @param data
     *            响应数据
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> build(String code, List<String> errorMsg, Map<String,String> noteMsg, T data) {
        ServerResponse<T> res = new ServerResponse<>();
        if (errorMsg != null && !errorMsg.isEmpty()) {
            res.addErrorMsg(errorMsg);
        }
        if (noteMsg != null && !noteMsg.isEmpty()) {
            res.setNoteMsg(noteMsg);
        }
        if(data!=null){
            res.setData(data);
        }
        return res;
    }
    /**
     *
     * <p>Title: buildToJsonString</p>
     * <p>Description: 创建一个响应数据，并转换成json字符串 </p>
     * @param code
     *            响应状态码
     * @param errorMsg
     *            错误信息
     * @param noteMsg
     *            提示信息
     * @param data
     *            响应数据
     * @return String
     * @throws JsonProcessingException
     */
    public static <T> String buildToJsonString(String code, List<String> errorMsg, Map<String,String> noteMsg, T data) throws JsonProcessingException {
        return ServerResponse.build(code, errorMsg, noteMsg, data).toJsonString();
    }
    /**
     *
     * <p>
     * Title: ok
     * </p>
     * <p>
     * Description: 创建一个响应数据(结果为success)
     * </p>
     *
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> ok() {
        ServerResponse<T> res = new ServerResponse<>();
        res.setStatus(200);
        return res;
    }
    /**
     *
     * <p>Title: ok</p>
     * <p>Description: 创建一个响应数据(结果为success) </p>
     *
     * @param data 响应数据
     * @return ServerResponse
     */
    public static <T> ServerResponse<T> ok(T data) {
        ServerResponse<T> res = new ServerResponse<>();
        res.setStatus(200);
        res.setData(data);
        return res;
    }
    /**
     *
     * <p>Title: okToJsonString</p>
     * <p>Description: 创建一个响应数据,并转换成json字符串(结果为success) </p>
     *
     * @param data 响应数据
     * @return String
     * @throws JsonProcessingException
     */
    public static <T> String okToJsonString(T data) throws JsonProcessingException {
        return ServerResponse.ok(data).toJsonString();
    }
    /**
     *
     * <p>Title: okToJsonString</p>
     * <p>Description: 创建一个响应数据,并按照给定的日期格式转换成json字符串(结果为success) </p>
     *
     * @param data 响应数据
     * @param pattern 日期格式
     * @return
     * @throws JsonProcessingException
     */
    public static <T> String okToJsonString(T data,String pattern) throws JsonProcessingException {
        return ServerResponse.ok(data).toJsonString(pattern);
    }
}
